import fs from 'fs-extra'
import path from 'path'
import { listDir, removeEmptyDirs } from './tools/fs.js'
import { readGUID } from './tools/unity.js'

declare interface UsedMap { [guid: string]: string[] }

export class FileUsing {
    private static instance: FileUsing
    public static get Instance (): FileUsing {
        if (FileUsing.instance === undefined) {
            FileUsing.instance = new FileUsing()
        }
        return FileUsing.instance
    }

    public async collectUselessImgs (projectRoot: string): Promise<void> {
        console.log('start collecting useless images...')

        const usedMap = await this.collectGUID(projectRoot)

        const imgs = await listDir(path.join(projectRoot, 'Assets/AssetSources/ui/atlas'), ['.png', '.jpg', '.tga'])
        console.log(`${imgs.length} images found`)
        const uselessImgs: string[] = []
        for (const img of imgs) {
            const imgMeta = img + '.meta'
            const guid = await readGUID(imgMeta)
            if (guid === undefined) {
                console.error('no meta:', guid)
            }
            if (guid === undefined || !(guid in usedMap)) {
                uselessImgs.push(img)
                await fs.unlink(img)
            }
        }
        console.log(`${uselessImgs.length} images never be used`)

        await removeEmptyDirs(path.join(projectRoot, 'Assets/AssetSources/ui/atlas'))
    }

    public async getRefer (projectRoot: string, file: string): Promise<void> {
        const usedMap = await this.collectGUID(projectRoot)

        const fileMeta = path.join(projectRoot, file + '.meta')
        const guid = await readGUID(fileMeta)
        if (guid === undefined) {
            console.error('no meta:', guid)
        } else {
            const refers = usedMap[guid]
            console.log('refers count:', refers.length)
            for (const refer of refers) {
                console.log(refer)
            }
        }
    }

    private async collectGUID (projectRoot: string): Promise<UsedMap> {
        const prefabs = await listDir(path.join(projectRoot, 'Assets/AssetSources/ui'), ['.prefab'])
        prefabs.push(...await listDir(path.join(projectRoot, 'Assets/AssetSources/effect'), ['.prefab']))
        const usedMap: UsedMap = {}
        for (const prefab of prefabs) {
            const fcontent = await fs.readFile(prefab, 'utf-8')
            const result = fcontent.matchAll(/guid: (\w{32}),/g)
            for (const mr of result) {
                const guid = mr[1]
                let arr = usedMap[guid]
                if (arr == null) usedMap[guid] = arr = []
                arr.push(prefab)
            }
        }
        return usedMap
    }
}
